package com.shangyueshang.utils;

import com.google.common.collect.Multimap;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author Deycoesr@gmail.com
 * @since Fri 03/09/2021
 */
public abstract class CollectionUtil {

    public static boolean isEmpty(@Nullable Collection<?> collection) {
        return CollectionUtils.isEmpty(collection);
    }

    public static boolean isEmpty(@Nullable Map<?, ?> map) {
        return CollectionUtils.isEmpty(map);
    }

    public static boolean isEmpty(@Nullable Multimap<?, ?> multimap) {
        return (multimap == null || multimap.isEmpty());
    }

    public static boolean nonEmpty(@Nullable Map<?, ?> map) {
        return !isEmpty(map);
    }

    public static boolean nonEmpty(@Nullable Collection<?> collection) {
        return !isEmpty(collection);
    }

    public static boolean nonEmpty(@Nullable Multimap<?, ?> multimap) {
        return !isEmpty(multimap);
    }

    public static <T> List<T> beanCopyList(List<?> sourceList, Supplier<T> targetSupplier) {
        return beanCopyList(sourceList, targetSupplier, FunctionUtil.justReturnSecond());
    }

    private static <Source, Target> List<Target> beanCopyList(
            List<Source> sourceList,
            Supplier<Target> targetSupplier,
            BiFunction<Source, Target, Target> copiedThen
    ) {
        if (isEmpty(sourceList)) return new ArrayList<>();
        return sourceList.stream()
                .map(FunctionUtil.beanCopy(targetSupplier, copiedThen))
                .collect(Collectors.toList());
    }

    public static <T> SortedSet<T> beanCopySet(List<?> sourceList, Supplier<T> targetSupplier) {
        return beanCopySet(sourceList, targetSupplier, FunctionUtil.justReturnSecond());
    }

    private static <Source, Target> SortedSet<Target> beanCopySet(
            List<Source> sourceList,
            Supplier<Target> targetSupplier,
            BiFunction<Source, Target, Target> copiedThen
    ) {
        if (isEmpty(sourceList)) return new TreeSet<>();
        return sourceList.stream()
                .map(FunctionUtil.beanCopy(targetSupplier, copiedThen))
                .collect(Collectors.toCollection(TreeSet::new));
    }
}
